#coding=utf8

import re
import time
import urllib2
from cStringIO import StringIO
from hprose.io import *


class Parser:
    __log_name = ['remote_addr', 'remote_user', 'time_local', 'request', 'status', 'body_bytes_sent', 'request_body', 'http_referer', 'http_user_agent', 'http_x_forwarded_for']

    __request_name = ['request_method', 'request_url', 'request_version']

    __time_name = ('day', 'month', 'year', 'hour', 'minute', 'seconds')

    __month_dict = {'Jan': '1', 'Feb': '2', 'Mar': '3', 'Apr': '4', 'May': '5', 'Jun': '6', 'Jul': '7', 'Aug': '8', 'Sept': '9', 'Oct': '10', 'Nov': '11', 'Dec': '12'}

    __request_body_dict = {'authorize': ['appkey', 'uuid', 'userinfo', 'type'],
                           'pullBannerInFo': ['netType', 'token', 'pingmu', 'adDirect', 'type'],
                           'pullPauseInFo': ['netType', 'token', 'pingmu', 'type'],
                           'pullPOPInFo': ['netType', 'token', 'pingmu', 'zoneCode', 'zoneValue', 'type'],
                           'showAdCT': ['uuid', 'adid', 'zoneName', 'token', 'rankid', 'type'],
                           'clickAdCT': ['uuid', 'adid', 'zoneName', 'token', 'rankid', 'type'],
                           'fetchOneAd': ['clientNums', 'netType', 'zoneType', 'token', 'pingmu', 'dataType'],
                           'bannerShow': ['netType', 'token', 'pingmu', 'adDirect', 'dataType']}

    __log = ''

    __is_parser_config = {}

    __split_log = {}

    __split_time = {}

    __split_request = {}

    __split_request_body = {}

    __split_http_user_agent = {}

    __split_ip = {}

    def __init__(self, log, is_parser_config):
        self.__log = log
        self.__is_parser_config = is_parser_config
        self.split_log()
        self.split_time()
        self.split_request()
        self.split_http_user_agent()
        self.split_ip()
        self.split_request_body()

    def result(self):
        res = {}

        if self.__split_log:
            res.update(self.__split_log)

        if self.__split_time:
            res.update(self.__split_time)

        if self.__split_request:
            res.update(self.__split_request)

        if self.__split_http_user_agent:
            res.update(self.__split_http_user_agent)

        if self.__split_ip:
            res.update(self.__split_ip)

        if self.__split_request_body:
            res.update(self.__split_request_body)

        return res

    def split_log(self):
        parser_log = self.__log.replace('\n', '').split('@PC@')
        self.__split_log = dict(zip(self.__log_name, parser_log))

    def split_time(self):
        if 'time_local' in self.__split_log and self.__split_log.get('time_local') is not None and self.__split_log.get('time_local') != '-':
            pattern = re.compile(r'\[(\d+)/(\w+)/(\d+):(\d+):(\d+):(\d+).*?\]')
            match = pattern.match(self.__split_log.get('time_local'))
            if match:
                self.__split_time = dict(zip(self.__time_name, match.groups()))
                self.__split_time['month'] = self.__month_dict.get(self.__split_time.get('month'))
                self.__split_time['date'] = '%s-%s-%s' % (
                    self.__split_time['year'], self.__split_time['month'], self.__split_time['day'])
                self.__split_time['date_time'] = '%s-%s-%s %s:%s:%s' % (
                    self.__split_time['year'], self.__split_time['month'], self.__split_time['day'],
                    self.__split_time['hour'], self.__split_time['minute'], self.__split_time['seconds'])
                self.__split_time['timestamp'] = time.mktime(
                    time.strptime(self.__split_time['date_time'], '%Y-%m-%d %H:%M:%S'))

    def split_request(self):
        if 'request' in self.__split_log and self.__split_log.get('request') is not None and self.__split_log.get('request') != '-':
            parser_request = self.__split_log.get('request').split(' ')
            self.__split_request = dict(zip(self.__request_name, parser_request))

    def split_http_user_agent(self):
        if self.__is_parser_config.get('HTTP_USER_AGENT') and 'http_user_agent' in self.__split_log and self.__split_log.get('http_user_agent') is not None and self.__split_log.get('http_user_agent') != '-':
            pass

    def split_ip(self):
        if self.__is_parser_config.get('IP') and 'remote_addr' in self.__split_log and self.__split_log.get('remote_addr') is not None and self.__split_log.get('remote_addr') != '-':
            request_url = 'http://110.75.4.179/service/getIpInfo.php?ip=%s' % (self.__split_log.get('remote_addr'))
            parser_ip = eval(urllib2.urlopen(request_url).read())
            if 'code' in parser_ip and parser_ip.get('code') == 0:
                self.__split_ip = parser_ip.get('data')
                self.__split_ip['ip_info'] = parser_ip

    def split_request_body(self):
        if 'request_url' in self.__split_request and self.__split_request.get('request_url') == '/server' and 'request_body' in self.__split_log and self.__split_log.get('request_body') is not None and self.__split_log.get('request_body') != '-':
            __request_body = self.__split_log.get('request_body')

            __pattern = re.compile(r'^C(.*?)z$')
            __match = __pattern.match(__request_body)

            if __match:
                response = eval('"""' + __request_body + '"""')
                stream = StringIO(response)
                _filter = HproseFilter()
                reader = HproseReader(_filter.inputFilter(stream))
                except_tags = (HproseTags.TagCall, HproseTags.TagEnd)
                tag = reader.checkTags(except_tags)
                if tag == HproseTags.TagCall:
                    reader.reset()
                    function_name = reader.readString()
                    function_args = []
                    try:
                        tag = reader.checkTags((HproseTags.TagList,
                                                HproseTags.TagEnd,
                                                HproseTags.TagCall))
                        if tag == HproseTags.TagList:
                            reader.reset()
                            function_args = reader.readList(False)
                    except:
                        function_args = []

                if function_name is not None and function_args is not None and function_name in self.__request_body_dict:
                    self.__split_request_body = dict(zip(self.__request_body_dict.get(function_name), function_args))

                if function_args is not None:
                    function_args = str(function_args)

                if 'userinfo' in self.__split_request_body and self.__split_request_body.get('userinfo') is not None:
                    self.__split_request_body['userinfo'] = str(self.__split_request_body['userinfo'])

                self.__split_request_body['api'] = function_name
                self.__split_request_body['args'] = function_args
                del self.__split_log['request_body']